/**
 *
 */
package com.os.meituan.utils;

import cn.hutool.core.date.DateUtil;
import com.os.meituan.common.StringClass;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 *
 */
public class DateClass {

    public static Date parseDate(String dateStr) {
        Date targetDate = null;
        if (StringClass.hasValue(dateStr)) {
            try {
                dateStr = dateStr.trim().replace("T", " ").replace("Z", "");
                long longDate = Long.parseLong(dateStr);
                targetDate = new Date(longDate);
            } catch (NumberFormatException e) {
                try {
                    var pattern =
                            new String[]{"yyyy-MM","yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.S",
                                    "yyyy.MM.dd", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss.S",
                                    "yyyy/MM/dd", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss.S","HH:mm"};
                    targetDate = DateUtils.parseDate(dateStr, pattern);
                } catch (ParseException pe) {
                    targetDate = DateUtil.parseDate(dateStr);
                }
            }
        }


        return targetDate;
    }

    public static Date parseDate(String dateStr, String format) {
        return StringClass.isBlank(dateStr) ? null : DateUtil.parse(dateStr, format);
    }

    public static String toString(Date d, String format) {
        if (d == null) {
            d = new Date();
        }
        SimpleDateFormat sf = new SimpleDateFormat(format);
        return sf.format(d);
    }

    /**
     * 日期的开始时间
     *
     * @param date   当前时间
     * @return
     * @throws ParseException
     */
    public static Date getDayFirstDate(Date date) {
        Calendar scalendar = new GregorianCalendar();
        scalendar.setTime(date);
        scalendar.set(Calendar.HOUR_OF_DAY, 0);
        scalendar.set(Calendar.MINUTE, 0);
        scalendar.set(Calendar.SECOND, 0);
        scalendar.set(Calendar.MILLISECOND, 0);
        return scalendar.getTime();
    }

    /**
     * 月份的开始时间
     *
     * @param date
     * @param offset
     * @return
     * @throws ParseException
     */
    public static Date getMonthFirstDate(Date date, int offset) {
        Calendar scalendar = new GregorianCalendar();
        scalendar.setTime(date);
        scalendar.add(Calendar.MONTH, offset);
        scalendar.set(Calendar.DATE, 1);
        scalendar.set(Calendar.HOUR, 0);
        scalendar.set(Calendar.MINUTE, 0);
        scalendar.set(Calendar.SECOND, 0);
        scalendar.set(Calendar.MILLISECOND, 0);
        return scalendar.getTime();
    }

    public static int getYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.YEAR);
    }

    public static int getMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH);
    }

    public static int getDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_MONTH);
    }

    public static int getDayOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 获得真是的月份，默认会加1
     */
    public static int getRealyMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }

    /**
     * 获得一天的最后一刻
     */
    public static Date getDayEndDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar scalendar = new GregorianCalendar();
        scalendar.setTime(date);

        scalendar.set(Calendar.HOUR_OF_DAY, 23);
        scalendar.set(Calendar.MINUTE, 59);
        scalendar.set(Calendar.SECOND, 59);
        scalendar.set(Calendar.MILLISECOND, 999);
        return scalendar.getTime();
    }

    public static Date getMonthEndDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar scalendar = Calendar.getInstance();
        scalendar.setTime(date);
        scalendar.set(Calendar.DAY_OF_MONTH, scalendar
                .getActualMaximum(Calendar.DAY_OF_MONTH));
        scalendar.set(Calendar.HOUR, 23);
        scalendar.set(Calendar.MINUTE, 59);
        scalendar.set(Calendar.SECOND, 59);
        scalendar.set(Calendar.MILLISECOND, 999);
        return scalendar.getTime();
    }

    public static Date getMonthLastDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar
                .getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    public static Date getDay(Date date, int offset) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, offset);
        return calendar.getTime();
    }

    /**
     * @param date
     * @param offset
     * @return
     */
    public static Date getMinute(Date date, int offset) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, offset);
        return calendar.getTime();
    }
    /**
     * 获取时间的小时
     */
    public static int getHour(Date date, int offset) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, offset);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public static Date getFirstDay(String year, String month)
            throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.parse(year + "-" + month + "-1");
    }


    public static String getDate(Date date, String format, int offset) {
        if (StringClass.isNotBlank(format)) {
            Calendar scalendar = Calendar.getInstance();
            if (date == null) {
                scalendar.setTime(new Date());
            } else {
                scalendar.setTime(date);
            }
            if (format.length() == 6) {
                scalendar.add(Calendar.MONTH, offset);
            } else if (format.length() == 8) {
                scalendar.add(Calendar.DAY_OF_MONTH, offset);
            } else if (format.length() == 7) {
                if (format.indexOf("W") > 0) {
                    scalendar.add(Calendar.WEEK_OF_MONTH, offset);
                }
            }
            Date d = scalendar.getTime();
            SimpleDateFormat fmt = new SimpleDateFormat(format);
            return fmt.format(d);
        } else {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
            if (date == null) {
                return fmt.format(new Date());
            } else {
                return fmt.format(date);
            }
        }
    }

    public static String getCurDate() {
        String result;
        SimpleDateFormat smt = new SimpleDateFormat("yyyyMMddHHmmss");
        result = smt.format(new Date());
        return result;
    }

    public static String getCurDate(String format) {
        String result;
        SimpleDateFormat smt = new SimpleDateFormat(format);
        result = smt.format(new Date());
        return result;
    }

    public static String getDate(String format, Date date) {
        if (date == null) {
            return "";
        }
        String result;
        SimpleDateFormat smt = new SimpleDateFormat(format);
        result = smt.format(date);
        return result;
    }

    public static Date addDay(Date date, int days) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    public static Date addHour(Date date, int hour) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, hour);
        return cal.getTime();
    }

    public static Date addYear(Date date, int year) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, year);
        return cal.getTime();
    }

    /**
     * 计算两个日期间的间隔，d1-d2
     *
     * @param d1
     * @param d2
     * @param type 0分,1时,2天
     * @return
     */
    public static int dateDiff(Date d1, Date d2, int type) {
        int result = 0;
        if (d1 == null) {
            d1 = new Date();
        }
        if (d2 == null) {
            d2 = new Date();
        }
        long t1 = 0L;
        long t2 = 0L;
        if (d1 != null) {
            t1 = d1.getTime();
        }
        if (d2 != null) {
            t2 = d2.getTime();
        }
        // 因为t1-t2得到的是毫秒级,所以要初3600000得出小时.算天数或秒同理
        int hours = (int) ((t1 - t2) / 3600000);
        int minutes = (int) (((t1 - t2) / 1000 - hours * 3600) / 60);
        //int second = (int) ((t1 - t2) / 1000 - hours * 3600 - minutes * 60);
        if (type == 0) {
            result = (hours * 60) + minutes;
        } else if (type == 1) {
            result = hours;
        } else if (type == 2) {
            result = hours / 24;
        }
        return result;
    }

    /**
     * 仅进行年的比较，d1-d2
     */
    public static int dateDiffOnlyYear(Date d1, Date d2) {
        Calendar d11 = Calendar.getInstance();
        d11.setTime(d1);

        Calendar d22 = Calendar.getInstance();
        d22.setTime(d2);

        return d11.get(Calendar.YEAR) - d22.get(Calendar.YEAR);
    }

    public static int dateDiffOnlyMonth(Date d1, Date d2) {
        Calendar bef = Calendar.getInstance();
        Calendar aft = Calendar.getInstance();
        bef.setTime(d1);
        aft.setTime(d2);
        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
        return Math.abs(month + result);
    }

    /**
     * 比较2个日期相隔几年，返回大于等于0的数值(目前算法精度不足)
     */
    public static int dateDiffForYear(Date d1, Date d2) {
        var year1 = getYear(d1);
        var day1 = getDayOfYear(d1);

        var year2 = getYear(d2);
        var day2 = getDayOfYear(d2);

        if (year1 >= year2 && day1 >= day2) {
            return year1 - year2;
        } else {
            return Math.abs(year1 - year2) - 1;
        }
    }

    /**
     * 添加月分的0
     * @param dateStr 2019-9
     * @return 2019-09
     */
    public static String addMothWith0(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return "";
        }
        String[] arr = dateStr.split("-");
        if (arr[1].length() == 1) {
            arr[1] = "0" + arr[1];
        }
        return arr[0] + "-" + arr[1];
    }

    /**
     * 获取当年的第一天
     * @return
     */
    public static Date getCurrYearFirst() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    /**
     * 获取当年的最后一天
     */
    public static Date getCurrYearLast() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }

    /**
     * 获取某年第一天日期
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;

    }

    /**
     * 获取某年第一天日期
     */
    public static Date getYearFirst(Date date) {
        return getYearFirst(getYear(date));

    }

    /**
     * 获取某年最后一天日期
     * @param year
     * @return
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    public static Date getYearLast(Date date) {
        return getYearLast(getYear(date));

    }

    /**
     * 重设日期的年
     * @param date
     * @param year
     * @return
     */
    public static Date setYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 获得当前年月
     * @return yyyy-MM
     */
    public static String getCurYearMonth(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        return year + "-" + (month > 9 ? month : "0" + String.valueOf(month));
    }

    /**
     * 根据当前年月获取上一月份
     * @param curYearMonth
     * @return yyyy-MM
     */
    public static String getLastYearMonthByCurMonth(String curYearMonth){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        try {
            Date date = format.parse(curYearMonth);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
            return format.format(calendar.getTime());
        }catch (ParseException e){
            e.printStackTrace();
            return null;
        }
    }

}
